package com.company.cloud.common.security;

import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import cn.hutool.core.codec.Base64;


public class AesUtils {

	private static final String CHARSET_NAME = "UTF-8";
	private static final String AES_NAME = "AES";
	public static final String ALGORITHM = "AES/CBC/PKCS7Padding";

	/**
	 * HMACSHA256 加密
	 * 
	 * @param data 待处理数据
	 * @param key  密钥
	 * @return 加密结果 base64
	 * @throws Exception
	 */
	public static String encrypt_HMACSHA256(String data, String key) throws Exception {
		Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
		SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(CHARSET_NAME), "HmacSHA256");
		sha256_HMAC.init(secret_key);
		byte[] array = sha256_HMAC.doFinal(data.getBytes(CHARSET_NAME));
//		StringBuilder sb = new StringBuilder();
//		for (byte item : array) {
//			sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
//		}
		return Base64.encode(array);
	}

	/**
	 * HMACSHA256 解密
	 */
	public static String decrypt_HMACSHA256() {
		return null;
	}

	//--------------------------------------------------------
	
	/**
	 * AES/ECB/PKCS7Padding 加密
	 * @param data 待处理数据
	 * @param key  密钥
	 * @param iv  初始向量
	 * @return 加密结果 base64
	 * @throws Exception
	 */
	public static String encrypt_PKCS7Padding(String data,String key, String iv) throws Exception {
		byte[] _lv = null;
		if (iv != null && !"".equals(iv)) {
			_lv = iv.getBytes(CHARSET_NAME);
		}
		return encrypt_PKCS7Padding(data.getBytes(CHARSET_NAME), key.getBytes(CHARSET_NAME), _lv);
	}
	/**
	 * AES/ECB/PKCS7Padding 加密
	 * @return 加密结果 base64
	 * @throws Exception
	 */
	public static String encrypt_PKCS7Padding(byte[] data, byte[] key, byte[] iv) throws Exception {
        try {
        	if (Security.getProvider("BC") == null) {
				Security.addProvider(new BouncyCastleProvider());
			}
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            SecretKeySpec keySpec = new SecretKeySpec(key, AES_NAME);
            
			if (iv != null && iv.length > 0) {
				AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
				cipher.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec);
			} else {
				cipher.init(Cipher.ENCRYPT_MODE, keySpec);
			}
			return Base64.encode(cipher.doFinal(data));
        } catch (Exception e) {
        	e.printStackTrace();
			throw e;
        }
	}
	/**
	 * AES/ECB/PKCS7Padding 解密
	 */
	public static String decrypt_PKCS7Padding(String data, String key, String iv) throws Exception {
		byte[] _iv = null;
		if (iv != null && !"".equals(iv)) {
			_iv = iv.getBytes(CHARSET_NAME);
		}
		return decrypt_PKCS7Padding(data.getBytes(CHARSET_NAME), key.getBytes(CHARSET_NAME), _iv);
	}
	/**
	 * AES/ECB/PKCS7Padding 解密
	 */
	public static String decrypt_PKCS7Padding(byte[] data, byte[] key, byte[] iv) throws Exception {
		try {
			if (Security.getProvider("BC") == null) {
//				Security.addProvider(new BouncyCastleProvider());
			}
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			SecretKeySpec keySpec = new SecretKeySpec(key, AES_NAME);

			if (iv != null && iv.length > 0) {
				AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
				cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec);
			} else {
				cipher.init(Cipher.DECRYPT_MODE, keySpec);
			}
			return new String(cipher.doFinal(data));
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	


}
